package com.mangohouse.util;

import java.io.File;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.commons.io.FilenameUtils;
import org.apache.log4j.Logger;

import com.mangohouse.common.ReadConfigProperties;


/**
 * 
 * @TODO 上传文件工具类
 * @author roye
 * @date May 22, 2013 11:23:14 AM
 * @version V1.0
 */
public class UploadUtil {

	private static Logger logger = Logger.getLogger(UploadUtil.class);
	
	public static final String SPECIALNAME = "upfiles";
	
	/**
	 * 
	 * @todo 文件上传操作
	 * @author roye
	 * @date May 22, 2013 11:24:00 AM
	 * @param   
	 * @return Map   
	 * @throws
	 */
	@SuppressWarnings("unchecked")
	public static Map uploadfile(HttpServletRequest request) {

		String fileType = request.getParameter("filetype");// 获取文件扩展名
		if (fileType == null || fileType.equals("")){
			fileType = ".unknown";
		}
		fileType = fileType.toLowerCase();
		String proVal = request.getParameter("proVal");//对应上传配置路径中的KEY
		String type = request.getParameter("type");//扩展字段,标识哪种类型的上传
		String uploadTime = DateUtil.getDateFormat(new Date(), "yyyy-MM-dd HH:mm:ss");
		String tmpString =  DateUtil.getDateFormat(new Date(), "yyyyMMddHHmmsssss");
		String newFileName = tmpString + fileType;//生成新的文件名
		logger.debug("[" + fileType + "]...... Upload time:" + uploadTime
				+ " （IP:" + request.getRemoteAddr().toString() + "）" + proVal);
		DiskFileItemFactory factory = new DiskFileItemFactory();
		factory.setSizeThreshold(8192);// 每次内存读取字节数
		//获取保存文件的最终路径
		String saveFilePath;
		try {
			saveFilePath = getSavePath(proVal);
		} catch (Exception e2) {
			logger.error("----------获取上传路径异常!-----------");
			return null;
		}
		if (saveFilePath == null) {
			return null;
		}
		factory.setRepository(new File(saveFilePath));
		ServletFileUpload upload = new ServletFileUpload(factory);
		List uploadlist = null;
		try {
			uploadlist = upload.parseRequest(request);
		} catch (FileUploadException e1) {
			factory = null;
			upload = null;
			uploadlist = null;
			e1.printStackTrace();
			logger.error("  文件上传出现异常,路径：" + saveFilePath + "(" + uploadTime+ ")");
			// 如果是上传出现异常，删除文件
			FileUtil.del(saveFilePath);
			return null;
		}
		
		String oldFileName = "", actualFileSize = "";
		try {
			for (int i = 0; i < uploadlist.size(); i++) {
				FileItem item = (FileItem) uploadlist.get(i);
				if (!item.isFormField()) {// 处理文件上传域// 忽略其他不是文件域的所有表单信息
					try {
						long start = System.currentTimeMillis();
						actualFileSize = String.valueOf(item.getSize());// 获取文件大小
						String fullPath = item.getName();// 取到客户端完整 路径+文件名
						oldFileName = FilenameUtils.getName(fullPath);// 取到文件名
						item.write(new File(saveFilePath + newFileName));// 保存文件路径

						long end = System.currentTimeMillis();
						System.out.println("  save file："+ newFileName+ "(size："
								+ FileUtil.getAllFilesSizeWithUnit(String
										.valueOf(actualFileSize)) + " ，used："
								+ (end - start) + " ms)");

					} catch (Exception e) {
						logger.error("  文件上传出现异常" + saveFilePath + "(" + oldFileName+ ")");
						throw e;
					}
					item.delete();
					break;
				}
				item.delete();
			}
		} catch (Exception e) {
			e.printStackTrace();
			actualFileSize = null;
		} finally {
			factory = null;
			upload = null;
			uploadlist = null;
		}

		/*
		 * String[] rtnVal = new String[5]; rtnVal[0] = oldFileName;// 旧文件名
		 * rtnVal[1] = fileType;// 带点的扩展名，如 .wmv rtnVal[2] = newFileName;//
		 * 不带扩展名重命名的文件 rtnVal[3] = actualFileSize;// 文件大小 rtnVal[4] =
		 * saveFilePath;// 保存文件的绝对路径
		 */
		Map rtnMap = new HashMap();
		rtnMap.put("newName", newFileName);
		rtnMap.put("oldName", oldFileName);
		return rtnMap;
	}
	
	
	/**
	 * 
	 * @todo 多文件上传
	 * @author roye
	 * @date May 22, 2013 1:44:27 PM
	 * @param   
	 * @return Map   
	 * @throws
	 */
	@SuppressWarnings("unchecked")
	public static Map multiUploadfile(HttpServletRequest request) {

		// 获取文件扩展名
		String fileType = "";
		String proVal = request.getParameter("proVal");
		String newFileName = "";
		String name = "";
		DiskFileItemFactory factory = new DiskFileItemFactory();
		factory.setSizeThreshold(8192);// 每次内存读取字节数
		Map rtnMap = new HashMap();
		String saveFilePath = "";
		try {
			saveFilePath = getSavePath(proVal);
		} catch (Exception e2) {
			logger.error("----------获取上传路径异常!-----------");
			return null;
		}
		if (saveFilePath == null) {
			return null;
		}
		factory.setRepository(new File(saveFilePath));
		ServletFileUpload upload = new ServletFileUpload(factory);
		List uploadlist = null;
		try {
			uploadlist = upload.parseRequest(request);
		} catch (FileUploadException e1) {
			factory = null;
			upload = null;
			uploadlist = null;
			e1.printStackTrace();
			logger.error("  文件上传出现异常" + saveFilePath + ")");
			// 如果是上传出现异常，删除文件
			FileUtil.del(saveFilePath);
			return null;
		}

		String oldFileName = "", actualFileSize = "";
		try {
			for (int i = 0; i < uploadlist.size(); i++) {
				FileItem item = (FileItem) uploadlist.get(i);
				if (!item.isFormField()) {// 处理文件上传域// 忽略其他不是文件域的所有表单信息
					try {
						long start = System.currentTimeMillis();
						actualFileSize = String.valueOf(item.getSize());// 获取文件大小
						String fullPath = item.getName();// 取到客户端完整 路径+文件名
						oldFileName = FilenameUtils.getName(fullPath);// 取到文件名

						// 扩展名格式：
						if (oldFileName.lastIndexOf(".") >= 0) {
							fileType = oldFileName.substring(oldFileName
									.lastIndexOf("."));
						}

						if (fileType == null || fileType.equals(""))
							fileType = ".unknown";
						fileType = fileType.toLowerCase();
						//name是文件名唯一标识
						name = UUID.randomUUID().toString().replaceAll("-", "");
						String tmpString =  DateUtil.getDateFormat(new Date(), "yyyyMMddHHmmsssss");
						String uploadTime = DateUtil.getDateFormat(new Date(), "yyyy-MM-dd HH:mm:ss");
						newFileName = tmpString + name + fileType;
						System.out.println("[" + fileType
								+ "]...... Upload time:" + uploadTime + " （IP:"
								+ request.getRemoteAddr().toString() + "）");
						rtnMap.put("/"+SPECIALNAME + "/" + newFileName, oldFileName);
						item.write(new File(saveFilePath + newFileName));// 保存文件路径

						long end = System.currentTimeMillis();
						System.out.println("  save file："
								+ newFileName
								+ "(size："
								+ FileUtil.getAllFilesSizeWithUnit(String
										.valueOf(actualFileSize)) + " ，used："
								+ (end - start) + " ms)");

					} catch (Exception e) {
						e.printStackTrace();
						throw e;
					}
					item.delete();

					break;
				}
				item.delete();
			}
		} catch (Exception e) {
			e.printStackTrace();
			actualFileSize = null;
		} finally {
			factory = null;
			upload = null;
			uploadlist = null;
		}

		/*
		 * String[] rtnVal = new String[5]; rtnVal[0] = oldFileName;// 旧文件名
		 * rtnVal[1] = fileType;// 带点的扩展名，如 .wmv rtnVal[2] = newFileName;//
		 * 不带扩展名重命名的文件 rtnVal[3] = actualFileSize;// 文件大小 rtnVal[4] =
		 * saveFilePath;// 保存文件的绝对路径
		 */
		return rtnMap;
	}

	/**
	 * 
	 * @todo 获取保存文件的全路径
	 * @author roye
	 * @date May 22, 2013 11:57:00 AM
	 * @param   proVal 配置文件中的KEY
	 * @return String   
	 * @throws Exception 
	 * @throws
	 */
	private static String getSavePath(String proVal) throws Exception {

		if (proVal != null && proVal.equals("")) {
			proVal = "";
		}
		String saveFilePath = ReadConfigProperties.FILEUPLOAD_BASE_PATH + ReadConfigProperties.getPropValue(proVal);
		if (saveFilePath == null || saveFilePath.equals("")) {
			return null;
		}
		saveFilePath += "/" + SPECIALNAME;
		if (!saveFilePath.endsWith("/"))
			saveFilePath += "/";

		// 生成文件保存路径
		File aSaveFile = new File(saveFilePath);
		if (!aSaveFile.isDirectory())
			aSaveFile.mkdirs();
		return saveFilePath;
	}
	
	
	
	
}
